package org.example.controller;

import org.example.utils.MyRunnable;
import org.example.service.AsyncService;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scripting.support.StaticScriptSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/api")
public class MyController {

    @Autowired
    private RedissonClient redissonClient;

    private ThreadPoolTaskExecutor taskExecutor;

    private final ConcurrentHashMap<String, Boolean> taskStatus = new ConcurrentHashMap<>();

    RBlockingDeque<Runnable> blockingDeque ;

    @PostConstruct
    public void init() {
        taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.initialize();
        blockingDeque = redissonClient.getBlockingDeque("my-queue");
    }

    @PreDestroy
    public void destroy() {
        taskExecutor.shutdown();
    }

    @GetMapping("/start-thread")
    public String startThread() {
        taskExecutor.execute(() -> {
            try {
                // 模拟耗时操作
                Thread.sleep(5000);
                System.out.println("子线程任务完成");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("子线程被中断: " + e.getMessage());
            }
        });

        return "子线程已启动";
    }

    @GetMapping("/start-thread-redisson/{id}")
    public String startThreadRedisson(@PathVariable("id") String id) {
//        RScheduledExecutorService executorService = redissonClient.getExecutorService("my-service", ExecutorOptions.defaults());
//        executorService.execute(new MyRunnable());
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                blockingDeque);
        for (int i = 0; i < 10; i++) {
            threadPoolExecutor.execute(new MyRunnable(id,i));
        }
        return "子线程已启动";
    }


    public static AsyncService asyncService;

    @GetMapping("/start-async-task")
    public String startAsyncTask() {
        asyncService.performAsyncTask();
        return "异步任务已启动";
    }
    @Autowired
    private MyWebSocketHandler webSocketHandler;
    @GetMapping("/start-completable-future/{taskId}")
    public String startCompletableFuture(@PathVariable String taskId) {
        taskStatus.put(taskId, false);
        CompletableFuture.runAsync(() -> {
            try {
                // 模拟耗时操作
                Thread.sleep(5000);
                System.out.println("CompletableFuture 任务完成");
                taskStatus.put(taskId, true);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("CompletableFuture 任务被中断: " + e.getMessage());
            }
        });

        return "CompletableFuture 任务已启动";
    }
    @GetMapping("/check-task-status/{taskId}")
    public String checkTaskStatus(@PathVariable String taskId) {
        Boolean status = taskStatus.get(taskId);
        if (status == null) {
            return "任务不存在";
        }
        return "任务状态: " + (status ? "完成" : "进行中");
    }


    @GetMapping("/start-async-task-sse")
    public SseEmitter startAsyncTaskSse() {
        SseEmitter emitter = new SseEmitter();

        CompletableFuture.runAsync(() -> {
            try {
                // 模拟耗时操作
                Thread.sleep(5000);
                System.out.println("异步任务完成");

                // 通过 SSE 发送消息
                emitter.send(SseEmitter.event()
                        .id("1")
                        .name("taskCompleted")
                        .data("异步任务已完成"));
                emitter.complete();
            } catch (InterruptedException | IOException e) {
                Thread.currentThread().interrupt();
                System.err.println("异步任务被中断: " + e.getMessage());
                emitter.completeWithError(e);
            }
        });

        return emitter;
    }

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/test_redis_lua/{ids}")
    public Set<String> testRedisLua(@PathVariable String[] ids) {
        int expireTime = 60;
        String uuidKey = "test_uuid";
        String luaScript =
                "local result_key = KEYS[1]\n" +
                        "local ids = ARGV\n" +
                        "local unique_ids = {}\n" +
                        "for _, id in ipairs(ids) do\n" +
                        "    local key = result_key .. ':' .. id\n" +
                        "    local is_set = redis.call('SET', key, '"+uuidKey+"', 'NX', 'EX', "+expireTime+")\n" +
                        "    if is_set then\n" +
                        "        table.insert(unique_ids, id)\n" +
                        "    else\n" +
                        "        redis.call('SET', key, '"+uuidKey+"', 'EX', "+expireTime+")\n" +
                        "    end\n" +
                        "end\n" +
                        "return unique_ids\n";
        DefaultRedisScript<Set> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptSource(new StaticScriptSource(luaScript));
        redisScript.setResultType(Set.class);

        return stringRedisTemplate.execute(redisScript, Arrays.asList("test_uniq_key_prefix_"), ids);

    }

    @GetMapping("/test_regex")
    public String testRegex() {
        String str = "(?i)jk_customer$|jk_customer\\s+";
        String str1 = "(?i)jk_contact|jk_contact\\s+";
        Pattern pattern = Pattern.compile(str);
        Pattern pattern1 = Pattern.compile(str1);
        String combinedRegex = "(?i)(jk_customer$|jk_customer\\s+)|(jk_contact$|jk_contact\\s+)";
        Pattern combinedPattern = Pattern.compile(combinedRegex);
        // 测试字符串
        String[] testStrings = {
                "SELECT * FROM jjk_customer",
                "SELECT * FROM jk_customer WHERE id = 1",
                "SELECT * FROM JK_CUSTOMER",
                "SELECT * FROM jk_customer;",
                "SELECT * FROM jk_customer_order", // 不会被匹配
                "SELECT * FROM jk_contact",
                "SELECT * FROM jk_contact WHERE id = 1",
                "SELECT * FROM JK_CONTACT",
                "SELECT * FROM jk_customer JOIN jk_contact ON jk_customer.id = jk_contact.id",
                "SELECT * FROM jk_contact;" // 会被匹配
        };

        for (String testString : testStrings) {
            Matcher matcher = combinedPattern.matcher(testString);
            if (matcher.find()) {
                System.out.println("匹配成功: " + testString);
                if (matcher.group(1) != null) {
                    System.out.println("匹配到 jk_customer: " + testString);
                }
                if (matcher.group(2) != null) {
                    System.out.println("匹配到 jk_contact: " + testString);
                }
            } else {
                System.out.println("未匹配: " + testString);
            }
        }
        return "testRegex";
    }
}
